package cc.wanforme.st.server.base.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cc.wanforme.st.server.authen.dto.AdminRoleAuth;
import cc.wanforme.st.server.authen.service.TokenService;
import cc.wanforme.st.server.base.constant.UserStatus;
import cc.wanforme.st.server.base.entity.AuthToken;
import cc.wanforme.st.server.base.entity.RolePermission;
import cc.wanforme.st.server.base.entity.Admin;
import cc.wanforme.st.server.base.entity.AdminRole;
import cc.wanforme.st.server.base.mapper.AdminMapper;
import cc.wanforme.st.server.base.service.IRolePermissionService;
import cc.wanforme.st.server.base.service.IAdminRoleService;
import cc.wanforme.st.server.base.service.IAdminService;
import cc.wanforme.st.server.util.AssertCheck;
import cc.wanforme.st.server.util.PasswordUtil;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

/**
 * <p>
 * 用户表（不实现评论和留言，但是保留） 服务实现类
 * </p>
 *
 * @author wanne
 * @since 2020-09-18
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin>
	implements IAdminService {

	@Autowired
	private TokenService tokenService;
	@Autowired
	private IAdminRoleService roleService;
	@Autowired
	private IRolePermissionService roleAuthService;
	
	@Override
	public Admin selectByUsername(String username) {
		return this.baseMapper.selectByUsername(username);
	}
	
	/** 获取用户的角色和权限（建议加入缓存）<br>
	 * 注：没有查询 Admin 信息
	 * @param adminId
	 * @return
	 */
	public AdminRoleAuth selectAuthenticationsByAdmin(long adminId) {
		AdminRoleAuth re = new AdminRoleAuth();
		List<AdminRole> roles = roleService.selectRoles(adminId);
		Admin admin = this.getById(adminId);
		
		Assert.notNull(admin, "未查到此用户");
		re.setAdmin(admin);
		
		if(roles==null) {
			return re;
		}
		
		for (AdminRole role : roles) {
			List<RolePermission> auths = roleAuthService.selectPermissions(role.getRole());
			if(auths == null) {
				auths = new ArrayList<>(0);
			}
			re.getRoleAuth().put(role, auths);
		}
		
		return re;
	}
	
	/** 根据 token 查出对应用户的角色和权限<br> 
	 * token 不存在时，会跑出异常
	 * @param token
	 * @return
	 */
	public AdminRoleAuth selectAuthenticationsByToken(String token) {
		Long adminId = tokenService.getIdByToken(token);
		
		if(adminId==null) {
			AuthToken authToken = tokenService.selectValidToken(token);
			Assert.notNull(authToken, "登录信息已过期");
			adminId = authToken.getUserId();
		}
		
		Assert.notNull(adminId, "请先登录");
		
		return this.selectAuthenticationsByAdmin(adminId);
	}
	
	public Admin selectAdminByToken(String token) {
		Long adminId = tokenService.getIdByToken(token);
		if(adminId==null) {
			AuthToken authToken = tokenService.selectValidToken(token);
			Assert.notNull(authToken, "用户登录信息已过期");
			adminId = authToken.getUserId();
		}
		
		if(adminId==null) {
			return null;
		}
		
		Admin user = this.getById(adminId);
		return user;
	}

	@Override
	public Admin saveVo(Admin vo) {
		AssertCheck.nonNull(vo.getName(), "缺少昵称");
		AssertCheck.nonNull(vo.getUsername(), "缺少用户名");
		AssertCheck.nonNull(vo.getPassword(), "缺少密码");
		
		vo.setPassword(PasswordUtil.encodePassword(vo.getPassword()));
		
		this.save(vo);
		return vo;
	}

	@Override
	public void updateVo(Admin vo) {
		AssertCheck.nonNull(vo.getId(), "未知用户");
		AssertCheck.nonNull(vo.getName(), "缺少昵称");
		AssertCheck.nonNull(vo.getUsername(), "缺少用户名");
		
		vo.setPassword(null);
		this.updateById(vo);
	}
	
	@Override
	public void resetPwd(Long id, String password) {
		AssertCheck.nonNull(password, "请输入新密码");
		
		Admin po = this.getById(id);
		AssertCheck.nonNull(po, "用户不存在!");
		
		po.setPassword(PasswordUtil.encodePassword(password));
		this.updateById(po);
	}

	@Override
	public void deleteAdmin(String id) {
		Admin admin = this.getById(id);
		AssertCheck.nonNull(admin, "用户不存在");
		
		admin.setStatus(UserStatus.DELETE.getCode());
		this.updateById(admin);
	}

	@Override
	public void resetPassword(String adminId, String password) {
		Admin admin = this.getById(adminId);
		AssertCheck.nonNull(admin, "用户不存在");
		
		admin.setPassword(PasswordUtil.encodePassword(password));
		this.updateById(admin);
	}

	
	@Override
	public PageInfo<Admin> searchAdmins(int page, int pageSize, String name, String username) {
		PageHelper.startPage(page, pageSize);
		List<Admin> list = this.baseMapper.listUsers(name, username);
		return new PageInfo<Admin>(list);
	}
}
